<template>
  <div class="home">
    <div id="all" ref="all">
      <input
        type="text"
        class="inp1"
        @focus="inputFoc1"
        @blur="inputBlur1"
        @keyup.enter="inputBlur1"
        v-model.number="inp1"
        placeholder="请输入初值"
        @change="leftInputChange"
      />
      <p class="startBefore">
        <slot name="beforeIcon"></slot>
      </p>
      <p class="startAfter">
        <slot name="firstAfterIcon"></slot>
      </p>
      <p class="endBefore">
        <slot name="lastBeforeIcon"></slot>
      </p>
      <p class="endAfter">
        <slot name="lastAfterIcon"></slot>
      </p>
      <p class="midTxt">{{ midtext }}</p>
      <input
        type="text"
        class="inp2"
        @focus="inputFoc2"
        @keyup.enter="inputBlur2"
        @blur="inputBlur2"
        v-model.number="inp2"
        placeholder="请输入终值"
        @change="rightInputChange"
      />
    </div>
  </div>
</template>

<script>
// @ is an alias to /src

export default {
  name: "myNum",
  model: {
    prop: "val",
    event: "numChange",
  },
  props: {
    precision: [Array, Number], // 精度，保留小数的位数，数组的时候分别代表左右精度，否则为两侧精度
    // 两个框中间的文字
    midtext: {
      type: String,
      default: "至",
    },
    // 回显值
    val: {
      type: Array,
    },
    // 设定最大最小值
    min: [Number],
    max: [Number],
  },
  data() {
    return {
      inpValue: "",
      inp1: "",
      inp2: "",
    };
  },
  methods: {
    leftInputChange(e) {
      this.$emit("leftInputChange", e, e.target.value);
    },
    rightInputChange(e) {
      this.$emit("rightInputChange", e, e.target.value);
    },
    inputFoc1() {
      this.$refs.all.style.border = "1px solid #409EFF";
    },
    inputBlur1() {
      this.$refs.all.style.border = "1px solid #dcdfe6";
      if (Number.isNaN(Number.parseFloat(this.inp1))) {
        this.inp1 = "";
      }

      if (this.inp2 !== "" && this.inp1 !== "") {
        if (this.inp2 * 1 < this.inp1 * 1) {
          [this.inp1, this.inp2] = [this.inp2, this.inp1];
        }
      }

      if (this.min !== "" && this.min !== undefined && this.min !== null) {
        this.inp1 = Math.max(this.inp1, this.min);
      }
      if (this.max !== "" && this.max !== undefined && this.max !== null) {
        this.inp2 = Math.min(this.inp2, this.max);
      }
      this.precisionProcessing();
      this.$emit("numChange", [this.inp1, this.inp2]);
    },
    inputFoc2() {
      this.$refs.all.style.border = "1px solid #409EFF";
    },
    inputBlur2() {
      this.$refs.all.style.border = "1px solid #dcdfe6";
      if (Number.isNaN(Number.parseFloat(this.inp2))) {
        this.inp2 = "";
      }

      if (this.inp2 !== "" && this.inp1 !== "") {
        if (this.inp2 * 1 < this.inp1 * 1) {
          [this.inp1, this.inp2] = [this.inp2, this.inp1];
        }
      }
      if (this.min !== "" && this.min !== undefined && this.min !== null) {
        this.inp1 = Math.max(this.inp1, this.min);
      }
      if (this.max !== "" && this.max !== undefined && this.max !== null) {
        this.inp2 = Math.min(this.inp2, this.max);
      }
      this.precisionProcessing();
      this.$emit("numChange", [this.inp1, this.inp2]);
    },
    // 精度处理函数
    precisionProcessing() {
      if (this.precision !== undefined && this.precision !== null) {
        switch (this.precision.constructor) {
          case Array:
            if (this.precision.length == 1) {
              this.inp1 === ""
                ? (this.inp1 = "")
                : (this.inp1 = (this.inp1 * 1).toFixed(this.precision[0]));
              this.inp2 === ""
                ? (this.inp2 = "")
                : (this.inp2 = (this.inp2 * 1).toFixed(this.precision[0]));
            } else {
              this.inp1 === ""
                ? (this.inp1 = "")
                : (this.inp1 = (this.inp1 * 1).toFixed(this.precision[0]));
              this.inp2 === ""
                ? (this.inp2 = "")
                : (this.inp2 = (this.inp2 * 1).toFixed(this.precision[1]));
            }
            break;
          case Number:
            this.inp1 === ""
              ? (this.inp1 = "")
              : (this.inp1 = (this.inp1 * 1).toFixed(this.precision));
            this.inp2 === ""
              ? (this.inp2 = "")
              : (this.inp2 = (this.inp2 * 1).toFixed(this.precision));
            break;
          default:
            return false;
        }
      }
    },
    // 运行警告
    warning() {
      // 精度警告
      if (this.precision !== void 0 && this.precision !== null) {
        if (this.precision.constructor == Array) {
          if (!this.precision.length || this.precision.length > 2) {
            throw new Error("精度不许为空数组，如果是数组，其长度必须是1或者2");
          }
          this.precision.forEach((it) => {
            if (!Number.isInteger(it) || it < 0)
              throw new Error("精度必须是有限的正整数");
          });

          if (this.precision.length === 2) {
            this.inp1 = (this.inp1 * 1).toFixed(this.precision[0]);
            this.inp2 = (this.inp2 * 1).toFixed(this.precision[1]);
          } else {
            this.inp1 = (this.inp1 * 1).toFixed(this.precision[0]);
            this.inp2 = (this.inp2 * 1).toFixed(this.precision[0]);
          }
        } else {
          let flag = this.precision * 1;
          if (!Number.isInteger(flag) || flag < 0)
            throw new Error("精度必须是有限的正整数");

          this.inp1 = (this.inp1 * 1).toFixed(flag);
          this.inp2 = (this.inp2 * 1).toFixed(flag);
        }
      }
      //   值警告
      if (this.val.length !== 2) throw new Error("输入的数组长度必须为2");
      this.numberValid(this.val);
      const min = this.min;
      const max = this.max;
      this.numberValid(min);
      this.numberValid(max);
      if (max <= min) {
        throw new Error("最大值必须大于等于最小值");
      }
    },
    // 数字校验
    numberValid(item) {
      console.log(item);
      if (item !== undefined && item !== null) {
        switch (item.constructor) {
          case String:
          case Number:
            if (Number.isNaN(item * 1)) {
              throw new Error("输入的必须为数字或者字符串数字！");
            }
            if (item.constructor === String) {
              if (item.replaceAll(" ", "") === "")
                throw new Error("输入的不允许是空字符串");
            }
            break;
          case Array:
            item.forEach((it) => {
              if (Number.isNaN(it * 1))
                throw new Error("输入的必须为数字或者字符串数字！");
              if (it.constructor === String) {
                if (it.replaceAll(" ", "") === "")
                  throw new Error("输入的不允许是空字符串");
              }
            });
            break;
          default:
            break;
        }
      }
    },
  },
  mounted() {
    var t = this.$watch(
      "val",
      (n) => {
        this.inpValue = n;
        if (this.inpValue[1] * 1 < this.inpValue[0] * 1) {
          [this.inpValue[0], this.inpValue[1]] = [
            this.inpValue[1] * 1,
            this.inpValue[0] * 1,
          ];
        }
        console.log(this.inpValue);
        if (this.min !== "" && this.min !== undefined && this.min !== null) {
          this.inp1 = Math.max(this.inpValue[0], this.min); //23
        } else {
          this.inp1 = this.inpValue[0];
        }
        if (this.max !== "" && this.max !== undefined && this.max !== null) {
          this.inp2 = Math.min(this.inpValue[1], this.max);
          this.inp1 = Math.min(this.inp1, this.max);
        } else {
          this.inp2 = this.inpValue[1];
        }
        if (this.min !== "" && this.min !== undefined && this.min !== null) {
          this.inp2 = Math.max(this.inp2, this.min);
        }

        this.$emit("numChange", [this.inp1, this.inp2]);
      },
      {
        immediate: true,
        deep: true,
      }
    );
    this.warning();
    t();
  },
};
</script>
<style lang="scss" scoped>
#all {
  width: 100%;
  min-width: 120px;
  display: flex;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  align-items: center;
  position: relative;
  padding: 3px 10px;
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  &:hover {
    border: 1px solid #c0c4cc;
  }
  .inp1 {
    width: 40%;
    text-align: center;
  }
  .inp2 {
    width: 40%;
    text-align: center;
    margin-left: 10px;
  }
  .midTxt {
    width: 5%;
    padding: 0 5px;
    text-align: center;
    min-width: 20px;
  }
  .startBefore {
    position: absolute;
    left: 5px;
    color: #c0c4cc;
  }
  .startAfter {
    position: absolute;
    left: calc(40% - 12px);
    color: #c0c4cc;
  }
  .endBefore {
    position: absolute;
    left: calc(45% + 11px);
    color: #c0c4cc;
  }
  .endAfter {
    position: absolute;
    left: calc(85% + 10px);
    color: #c0c4cc;
  }
}
</style>
